﻿using System.Linq;
using NczControlLibrary.Panels;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace NczControlLibrary.Controls {
    [TemplatePart(Name = "ip", Type = typeof(PanelPresentor))]
    public class NczListBox : Control {
        public NczListBox() {
            DefaultStyleKey = typeof(NczListBox);
        }
        PanelPresentor p;
        public override void OnApplyTemplate() {
            //presentor = GetTemplateChild("itemsPresentor") as PanelPresentor;
            p = GetTemplateChild("ip") as PanelPresentor;
            base.OnApplyTemplate();
        }
        #region VisualTreeHelper
        //http://www.cnblogs.com/jv9/archive/2010/06/28/1766459.html
        static public T GetChildObject<T>(DependencyObject obj, string name) where T : FrameworkElement {
            DependencyObject child = null;
            T grandChild = null;
            var count = VisualTreeHelper.GetChildrenCount(obj) - 1;
            for (int i = 0; i <= count; i++) {
                child = VisualTreeHelper.GetChild(obj, i);
                if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name))) {
                    return (T)child;
                } else {
                    grandChild = GetChildObject<T>(child, name);
                    if (grandChild != null)
                        return grandChild;
                }
            }
            return null;
        }
        static public List<T> GetChildObjects<T>(DependencyObject obj) where T : FrameworkElement {
            DependencyObject child = null;
            List<T> childList = new List<T>();
            var count = VisualTreeHelper.GetChildrenCount(obj) - 1;
            for (int i = 0; i <= count; i++) {
                child = VisualTreeHelper.GetChild(obj, i);
                if (child is T)
                    childList.Add(child as T);
            }
            return childList;
        }
        static public T GetParentObject<T>(DependencyObject obj, string name) where T : FrameworkElement {
            DependencyObject parent = VisualTreeHelper.GetParent(obj);
            while (parent != null) {
                if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name))) {
                    return (T)parent;
                }
                parent = VisualTreeHelper.GetParent(parent);
            }
            return null;
        }
        #endregion

        #region dependency
        public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(NczListBox), new PropertyMetadata(default(IEnumerable), (o, k) => {
        }));
        public IEnumerable ItemsSource {
            get { return (IEnumerable)this.GetValue(ItemsSourceProperty); }
            set {
                //foreach (var item in value) {
                //    p.Children.Add(new NczListBoxItem { Item = item ,Width=100,Height=22});
                //}
                this.SetValue(ItemsSourceProperty, value);
            }
        }
        public static readonly DependencyProperty ItemsPanelProperty = DependencyProperty.Register("ItemsPanel", typeof(ItemsPanelTemplate), typeof(NczListBox), new PropertyMetadata(ItemsPanel2Property, (o, k) => {
            var sender = o as NczListBox;
            //sender.p = (k.NewValue ?? k.OldValue) as NczWrapPanel;
        }));
        public ItemsPanelTemplate ItemsPanel { get { return (ItemsPanelTemplate)this.GetValue(ItemsPanelProperty); } set { this.SetValue(ItemsPanelProperty, value); } }
        public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(NczListBox), new PropertyMetadata(null, (o, k) => {
        }));
        public DataTemplate ItemTemplate { get { return (DataTemplate)this.GetValue(ItemTemplateProperty); } set { this.SetValue(ItemTemplateProperty, value); } }
        static readonly DependencyProperty ItemsPanel2Property = DependencyProperty.Register("ItemsPanel2", typeof(ItemsPanelTemplate), typeof(NczListBox), new PropertyMetadata(default(ItemsPanelTemplate), (o, k) => {
            var sender = o as NczListBox;
            //sender.p = GetChildObject<NczListBoxPanel>(k.NewValue as DependencyObject, "nlbp");
            //var xx = ((k.NewValue ?? k.OldValue) as ItemsPanelTemplate).GetValue();
            var x = 0.0d;
        }));
        internal ItemsPanelTemplate ItemsPanel2 { get { return (ItemsPanelTemplate)this.GetValue(ItemsPanel2Property); } set { this.SetValue(ItemsPanel2Property, value); } }
        #endregion
    }

    public class PanelPresentor : FrameworkElement {
        public PanelPresentor() {
        }
        public static readonly DependencyProperty ItemsPanelProperty = DependencyProperty.Register("ItemsPanel", typeof(ItemsPanelTemplate), typeof(PanelPresentor), new PropertyMetadata(default(ItemsPanelTemplate), (o, k) => {
        }));
        public ItemsPanelTemplate ItemsPanel { get { return (ItemsPanelTemplate)this.GetValue(ItemsPanelProperty); } set { this.SetValue(ItemsPanelProperty, value); } }
        public static readonly DependencyProperty ThePanelProperty = DependencyProperty.Register("ThePanel", typeof(Panel), typeof(PanelPresentor), new PropertyMetadata(default(Panel), (o, k) => {
        }));
        public Panel ThePanel { get { return (Panel)this.GetValue(ThePanelProperty); } set { this.SetValue(ThePanelProperty, value); } }
    }
    public class DataPresentor : FrameworkElement {
        public DataPresentor() {

        }
        public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(DataPresentor), new PropertyMetadata(default(DataTemplate), (o, k) => {
        }));
        public DataTemplate ItemTemplate { get { return (DataTemplate)this.GetValue(ItemTemplateProperty); } set { this.SetValue(ItemTemplateProperty, value); } }
    }
    [TemplatePart(Name = "dp", Type = typeof(DataPresentor))]
    public class NczListBoxItem : Control {
        public NczListBoxItem() {
            DefaultStyleKey = typeof(NczListBoxItem);
        }
        public override void OnApplyTemplate() {
            dp = GetTemplateChild("dp") as DataPresentor;
            base.OnApplyTemplate();
        }
        internal DataPresentor dp;
        public static readonly DependencyProperty ItemProperty = DependencyProperty.Register("Item", typeof(object), typeof(NczListBoxItem), new PropertyMetadata(default(object), (o, k) => {
        }));
        public object Item { get { return (object)this.GetValue(ItemProperty); } set { this.SetValue(ItemProperty, value); } }
    }
    public class NczListBoxPanel : System.Windows.Controls.VirtualizingPanel {
        protected override Size MeasureOverride(Size availableSize) {
            return base.MeasureOverride(availableSize);
        }
        protected override Size ArrangeOverride(Size finalSize) {
            return base.ArrangeOverride(finalSize);
        }
    }
    public class Editor :RichTextBox{
        string CheckKeyword(TextPointer current,LogicalDirection dir) {
            var checkmarks = new string[] {" ",",",".","+","-","*","/","=","(",")","[","]","@","!",":","?","&","#","$","`","~","|","\\",";",">","<"};
            var word = string.Empty;
            var currentchar = string.Empty;
            do {
                word +=currentchar= GetCurrentChar(current, dir);
            } while (!checkmarks.Contains(currentchar));
            return word;
        }
        string GetCurrentChar(TextPointer pointer, LogicalDirection direction) {
            TextPointer nextPointer = pointer.GetNextInsertionPosition(direction);
            if (nextPointer != null) {
                Selection.Select(pointer, nextPointer);
                if (Selection.Text.Length != 0)
                    return Selection.Text[0].ToString();
            }
            return "";
        }
    }
}
